<script>
import markerClass from './index.js';
import get from 'lodash-es/get.js';
import isEmpty from 'lodash-es/isEmpty.js';
import { pascalCase } from '@gis/lib/utils';
import { useUserInfoStore } from '@gis/lib/pinia/userInfo.js';

// console.log('markerClass: ', markerClass);
export default {
  name: 'cluster-v1',
  props: {
    mapGetter: { type: Function, default: undefined },
  },
  render() {
    return null;
  },
  computed: {
    area_code() {
      const userInfoStore = useUserInfoStore();
      return userInfoStore.area_code;
    },
  },
  created() {
    this.map = this.mapGetter();
    this.options = [];
    this.params = {};
    this.markerInstance = {};
    this.$watch(
      () => this.area_code,
      () => {
        this.init();
      },
      { immediate: false }
    );
    this.$vbus.$on('reloadMapMarkers', (params) => {
      this.init(null, params);
    });
  },
  unmounted() {
    this.destroy();
  },
  beforeDestroy() {
    this.destroy();
  },
  methods: {
    destroy() {
      this.$vbus.$off('reloadMapMarkers');
      this.clearLayer();
      if (this.layer) {
        this.layer.setMap(null);
      }
    },
    async init(options, params) {
      this.params = params;
      await this.loadPlugin();
      await this.createLayer();
      await this.clearLayer();
      this.render(options);
    },
    render(options) {
      /* option: [{node: "", leaf: []}] */
      if (options) {
        this.options = !Array.isArray(options) ? [options] : options;
      }
      this.options.forEach(async (option) => {
        // console.log('map-marker render option: ', option);
        // console.log('map-marker this.markerInstance: ', this.markerInstance);
        await this.createMarkers(option);
        await this.filterMarkers(option);
      });
    },
    async loadPlugin() {
      return await new Promise((resolve) => {
        if (AMap['MarkerClusterer']) {
          return resolve();
        }
        this.map.plugin(['AMap.MarkerClusterer'], () => {
          return resolve();
        });
      });
    },
    async createLayer() {
      return await new Promise((resolve) => {
        if (!this.layer) {
          this.layer = new AMap['MarkerClusterer'](this.map, [], {
            zIndex: 260,
            maxZoom: 17,
            gridSize: 80,
            renderClusterMarker: this.renderClusterMarker, // 自定义聚合点样式
            renderMarker: this.renderMarker,
          });
        }
        resolve();
      });
    },
    clearLayer() {
      this.markerInstance = {};
      if (this.layer) {
        // console.log('clearMarkers');
        this.layer.clearMarkers();
      }
    },
    createMarkerInstance(type) {
      type = pascalCase(type);
      const mClass = markerClass[type];
      // console.log('createMarkerInstance: ', type);
      // console.log('mClass: ', mClass);
      if (!mClass) {
        return console.error('can not find markerClass matched type: ', type, markerClass);
      }
      if (!this.markerInstance[type]) {
        this.markerInstance[type] = new mClass({ map: this.map, params: this.params });
      }
      return this.markerInstance[type];
    },
    async createMarkers(option = {}) {
      if (!option || isEmpty(option)) {
        return;
      }
      const { node } = option;
      if (!node) {
        return;
      }
      if (!this.markerInstance[node]) {
        this.markerInstance[node] = this.createMarkerInstance(node);
        if (!this.markerInstance[node]) {
          return;
        }
      }
      // ins.preIntercept.click = (e) => {
      // console.log("ins.preIntercept.click: ", e);
      // console.log("ins.preIntercept.click: ", this.layer.getMarkers());
      // };
      await this.markerInstance[node].ready();
    },
    async filterMarkers(option = {}) {
      // console.log('filterMarkers option: ', option);
      if (!option || isEmpty(option)) {
        return;
      }
      const ins = this.markerInstance[option.node];
      if (!ins) return;
      await ins.ready();
      ins.visibleMarkerType = option.leaf;
      /* 当没有子类型时显示该类型的所有marker,一般情况下不会出现这种情况 */
      if (!Array.isArray(ins.visibleMarkerType)) {
        const markers = ins.getMarkers().map((insItem) => ins.getMarker(insItem));
        this.layer.addMarkers(markers);
      } else {
        /* 当有子类型时依据子类型数组进行筛选 */
        const removes = [];
        const adds = [];
        ins.getMarkers().forEach((insItem) => {
          // console.log('ins.getMarkers().forEach: ', insItem);
          if (ins.visibleMarkerType.indexOf(insItem.type) < 0) {
            removes.push(ins.getMarker(insItem));
          } else {
            adds.push(ins.getMarker(insItem));
          }
        });
        // console.log('removes: ', removes);
        // console.log('adds: ', adds);
        this.layer.removeMarkers(removes);
        this.layer.addMarkers(adds);
      }
    },
    renderMarker(context) {
      // var content =
      //   '<div style="background-color: hsla(180, 100%, 50%, 0.3); height: 18px; width: 18px; border: 1px solid hsl(180, 100%, 40%); border-radius: 12px; box-shadow: hsl(180, 100%, 50%) 0px 0px 3px;"></div>';
      // var offset = new AMap.Pixel(-9, -9);
      // context.marker.setContent(content);
      // context.marker.setOffset(offset);
    },
    renderClusterMarker(context) {
      // console.log("renderClusterMarker: ", context);
      let size = this.getClusterMarkerSize(context);
      let content = context.marker.getContent();
      if (!content || get(content, 'attribute.name') !== 'ClusterMarker') {
        content = this.getClusterMarkerContent();
        content.setAttribute('name', 'ClusterMarker');
        context.marker.setContent(content);
      }
      context.marker.setOffset(new AMap.Pixel(-size / 2, -size / 2));
      this.setClusterMarkerStyle(content, context.count, size);
    },
    setClusterMarkerStyle(div, count, size) {
      div.style.width = div.style.height = size + 'px';
      div.style.borderRadius = size / 2 + 'px';
      div.style.lineHeight = size + 'px';
      div.innerHTML = count;
    },
    getClusterMarkerSize(context) {
      const count = this.layer.getClustersCount();
      return Math.round(20 + Math.pow(context.count / count, 1 / 5) * 20);
    },
    getClusterMarkerContent() {
      const bgColor = 'rgba(97,160,168,0.7)';
      const borderColor = 'rgba(97,160,168,0.9)';
      const shadowColor = 'rgba(75,206,217,0.7)';
      const div = document.createElement('div');
      div.style.backgroundColor = bgColor;
      div.style.border = '1px solid ' + borderColor;
      div.style.boxShadow = '0 0 5px ' + shadowColor;
      div.style.textAlign = 'center';
      div.style.fontSize = '14px';
      div.style.color = '#fff';
      return div;
    },
  },
};
</script>

<style scoped></style>
